﻿using System;
using System.Globalization;
using System.Threading;
using System.Web;
using System.Web.Configuration;
using System.Web.Mvc;
using System.Web.Routing;
using DiplomaWeb.Core;
using Diploma.Models;
using FluentValidation.Mvc;

namespace DiplomaWeb
{
    public class MvcApplication : HttpApplication
    {
        private static DataManager dataManager;

        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
        }

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute("LecturersThemes",
                "lecturers/{lecturerId}/themes",
                new
                    {
                        controller = "Students",
                        action = "LecturersThemes",
                        lecturerId = UrlParameter.Optional
                    });


            routes.MapPageRoute("FileManager",
                                "FileManagerForm.aspx",
                                "~/Views/FileManagerForm.aspx");

            routes.MapRoute(
                "Default",
                "{controller}/{action}/{id}",
                new
                    {
                        controller = "Account",
                        action = "LogOn",
                        id = UrlParameter.Optional
                    }
                );
        }

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            ControllerBuilder.Current.SetControllerFactory(new DiplomaControllerFactory());
            dataManager = DataManager.Instance;

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);

            FluentValidationModelValidatorProvider.Configure();
        }

        protected void Session_Start(object sender, EventArgs e)
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("ru");
        }

        protected void Application_AcquireRequestState(object sender, EventArgs e)
        {
            if (HttpContext.Current.Session != null)
            {
                var ci = (CultureInfo)Session["Culture"];

                if (ci == null || !(ci.Name.Equals("ru") || ci.Name.Equals("en")))
                {
                    string langName = "ru";
                    ci = new CultureInfo(langName);
                    Session["Culture"] = ci;
                }
                Thread.CurrentThread.CurrentUICulture = ci;
            }
        }

        public void Application_Error()
        {
            if (!Boolean.Parse(WebConfigurationManager.OpenWebConfiguration("~/").AppSettings.Settings["IsDebugMode"].Value))
            {
                var exception = Server.GetLastError();

                var errorId = Guid.NewGuid();
                if (exception != null)
                {
                    var newError = new DiplomaError
                                       {
                                           ErrorID = errorId,
                                           ErrorMessage = exception.Message,
                                           ErrorType = null,
                                           UserName = User.Identity.Name,
                                           Occured = DateTime.Now,
                                           IP = Request.UserHostAddress,
                                           Browser = Request.Browser.Browser,
                                           Level = String.Empty,
                                           Exception = exception.StackTrace
                                       };
                    dataManager.LoggerRepository.AddError(newError);
                }

                var httpException = exception as HttpException;
                var routeData = new RouteValueDictionary();

                if (httpException != null)
                {
                    switch (httpException.GetHttpCode())
                    {
                        case 404:
                            routeData = GetRouteFor404();
                            break;
                        default:
                            routeData = GetRouteFor500(errorId);
                            break;
                    }
                }
                else
                {
                    routeData = GetRouteFor500(errorId);
                }

                Response.Clear();
                Response.Expires = -1;
                Response.CacheControl = "no-cache";
                Response.Cache.SetNoStore();
                Response.Cache.SetNoServerCaching();
                Response.Cache.SetAllowResponseInBrowserHistory(false);
                Response.RedirectToRoute("Default", routeData);

                Server.ClearError();
            }
        }


        private RouteValueDictionary GetRouteFor404()
        {
            var routeData = new RouteValueDictionary();

            routeData["controller"] = "Error";
            routeData["action"] = "Http404";
            routeData["url"] = Request.Url.ToString();

            return routeData;
        }


        private static RouteValueDictionary GetRouteFor500(Guid errorId)
        {
            var routeData = new RouteValueDictionary();

            routeData["controller"] = "Error";
            routeData["action"] = "General";
            routeData["id"] = errorId;

            return routeData;
        }
    }
}